package org.ala.distributed_transaction_commons;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 分布式事务状态流转
 * <p>	2PC：
 * <p>		新建(new) -> 开启(begin) -> 待提交(pre_commit) -> 已提交(commited) -> 完成(finished)
 * <p>		新建(new) -> 开启(begin) -> 待提交(pre_commit) -> 回滚(rollback)
 * <p>		新建(new) -> 开启(begin) -> 回滚(rollback)
 * <p>	3PC：
 * <p>		新建(new) -> 开启(begin) -> 准备提交(can_commit) -> 待提交(pre_commit) -> 已提交(commited) -> 完成(finished)
 * <p>		新建(new) -> 开启(begin) -> 准备提交(can_commit) -> 待提交(pre_commit) -> 回滚(rollback)
 * <p>		新建(new) -> 开启(begin) -> 准备提交(can_commit) -> 回滚(rollback)
 * <p>		新建(new) -> 开启(begin) -> 准备提交(can_commit) -> 回滚(rollback)
 * 
 * @author 骆毅(ala)
 * @date 2024年2月17日
 */
public enum DistributedTransactionStatus {

	
	NEW(0, "new", "新建"),
	BEGIN(1, "begin", "开始"),
	CAN_COMMIT(2, "can_commit", "准备提交"),
	PRE_COMMIT(3, "pre_commit", "预提交"),
	COMMITED(4, "commited", "提交"),
	FINISHED(5, "finished", "完成：所有人都正确提交"),
	ROLLBACK(-1, "rollback", "回滚")
	;
	
	private int val;
	private String code;
	private String desc;
	private DistributedTransactionStatus(int val, String code, String desc) {
		this.val = val;
		this.code = code;
		this.desc = desc;
	}
	public int getVal() {
		return val;
	}
	public void setVal(int val) {
		this.val = val;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
	
	
	/**
	 * 小于等于
	 */
	public boolean lte(DistributedTransactionStatus status) {
		if (status == null) {return false;}
		return this.getVal() <= status.getVal();
	}
	/**
	 * 大于
	 */
	public boolean gte(DistributedTransactionStatus status) {
		if (status == null) {return false;}
		return this.getVal() >= status.getVal();
	}
	
	
	static Map<Integer, DistributedTransactionStatus> valMapper = null;
	static Object LOCK_VAL_MAPPER = new Object();
	/**
	 * 根据val查找
	 */
	public static DistributedTransactionStatus getInstance(int val) {
		if (valMapper == null) {
			synchronized (LOCK_VAL_MAPPER) {
				if (valMapper == null) {
					valMapper = Arrays.stream(DistributedTransactionStatus.values()).collect(Collectors.toMap(DistributedTransactionStatus::getVal, o->o, (o,n)->n));
				}
			}
		}
		return valMapper.get(val);
	}
	
	
}
